home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / ghostscr / gsview07.zip / display.c < prev    next >
C/C++ Source or Header  |  1993-04-30  |  19KB  |  726 lines

  1. /*
  2.  * display.c -- Ghostscript display operations for GSVIEW.EXE, 
  3.  *              a graphical interface for MS-Windows Ghostscript
  4.  * Copyright (C) 1993  Russell Lang
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *   Author: Russell Lang
  21.  * Internet: rjl@monu1.cc.monash.edu.au
  22.  */
  23.  
  24. #define STRICT
  25. #include <windows.h>
  26. #include <windowsx.h>
  27. #include <commdlg.h>
  28. #include <shellapi.h>
  29. #include <mmsystem.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <ctype.h>
  34. #include <dir.h>
  35. #define NeedFunctionPrototypes 1
  36. #include "ps.h"
  37. #include "gsview.h"
  38.  
  39. /* get current media index to papersizes[], or -1 if no match */
  40. int
  41. get_papersizes_index()
  42. {
  43. int i;
  44. char medianame[20];
  45.     GetMenuString(hmenu, media, medianame, sizeof(medianame), MF_BYCOMMAND);
  46.     for (i=0; papersizes[i].name != (char *)NULL; i++) {
  47.         if (!stricmp(papersizes[i].name, medianame))
  48.         return i;
  49.     }
  50.     return -1;
  51. }
  52.  
  53. /* calculate bitmap size for gswin */
  54. void
  55. gswin_size()
  56. {
  57. int i = get_papersizes_index();
  58.     if ( (xdpi == 0.0) || (ydpi == 0.0) )
  59.         xdpi = ydpi = DEFAULT_RESOLUTION;
  60.     epsf_clipped = FALSE;
  61.     switch (orientation) {
  62.         case IDM_LANDSCAPE:
  63.         case IDM_SEASCAPE:
  64.         if (i < 0) {
  65.             bitmap_width = user_height;
  66.             bitmap_height = user_width;
  67.         }
  68.         else {
  69.             bitmap_width = papersizes[i].height;
  70.             bitmap_height = papersizes[i].width;
  71.         }
  72.         break;
  73.         default:
  74.         if ((doc != (struct document *)NULL) && doc->epsf
  75.             && epsf_clip) {
  76.             epsf_clipped = TRUE;
  77.             bitmap_width = doc->boundingbox[URX] - doc->boundingbox[LLX];
  78.             bitmap_height = doc->boundingbox[URY] - doc->boundingbox[LLY];
  79.         }
  80.         else if (i < 0) {
  81.             bitmap_width = user_width;
  82.             bitmap_height = user_height;
  83.         }
  84.         else {
  85.             bitmap_width = papersizes[i].width;
  86.             bitmap_height = papersizes[i].height;
  87.         }
  88.     }
  89.     bitmap_width  = (unsigned int)(bitmap_width  / 72.0 * xdpi);
  90.     bitmap_height = (unsigned int)(bitmap_height / 72.0 * ydpi);
  91. }
  92.  
  93. /* change the size of the gswin image if open */
  94. void
  95. gswin_resize(void)
  96. {
  97. BOOL cfile_was_not_open = (cfile == (FILE *)NULL);
  98. BOOL display = FALSE;
  99.     gswin_size();
  100.     if (gswin_hinst == (HINSTANCE)NULL)
  101.         return;
  102.     if (cfile_was_not_open && redisplay 
  103.         && page_ready && (doc != (struct document *)NULL))
  104.             display = TRUE;    /* redisplay page after resize */
  105.     gsview_endfile();
  106.     if (cfile == (FILE *)NULL)
  107.         if (!open_cfile())
  108.             return;
  109.     if (gswin_hinst != (HINSTANCE)NULL) {
  110.         fprintf(cfile,"mark /HWSize [%u %u]\r\n",bitmap_width,bitmap_height);
  111.         fprintf(cfile,"/HWResolution [%g %g]\r\n",xdpi,ydpi);
  112.         fprintf(cfile,"currentdevice putdeviceprops pop erasepage flushpage\r\n");
  113.     }
  114.     if (display) {
  115.            fix_orientation(cfile);
  116.            dsc_header(cfile);
  117.         dsc_getpages(cfile,pagenum,pagenum);
  118.     }
  119.     if (cfile_was_not_open) {
  120.         close_cfile();
  121.         if (gswin_hinst != (HINSTANCE)NULL) {
  122.             set_timer(timeout);
  123.             pipe_file(cfname);
  124.         }
  125.     }
  126.     else {
  127.         if (cfile == (FILE *)NULL)
  128.             open_cfile();
  129.     }
  130. }
  131.  
  132.  
  133. /* run Ghostscript for previewing document */
  134. /* return 0 if ok, 1 if error */
  135. int
  136. gswin_open()
  137. {
  138. char command[256];
  139.     /* return if already open */
  140.     if ((gswin_hinst != (HINSTANCE)NULL) && IsWindow(hwndimgchild))
  141.         return 0;
  142.  
  143.     bPipeDone = FALSE;    /* so we wait for first request */
  144.     gswin_size();
  145.     sprintf(command,"%s -r%gx%g -g%ux%u -sGSVIEW=%u -",
  146.         szGSwin, xdpi, ydpi, bitmap_width, bitmap_height,
  147.         (unsigned int)hwndimg);
  148.     if (strlen(command) > 126) {
  149.         info_wait(FALSE);
  150.         gserror(IDS_TOOLONG, command, MB_ICONSTOP, SOUND_ERROR);
  151.         gswin_hinst = (HINSTANCE)NULL;
  152.         return 1;
  153.     }
  154.     gswin_hinst = (HINSTANCE)WinExec(command, SW_SHOWMINNOACTIVE);
  155.  
  156.     if (gswin_hinst < HINSTANCE_ERROR) {
  157.         info_wait(FALSE);
  158.         gserror(IDS_CANNOTRUN, command, MB_ICONSTOP, SOUND_ERROR);
  159.         gswin_hinst = (HINSTANCE)NULL;
  160.         return 1;
  161.     }
  162.     if (hwndtext == (HWND)NULL) {
  163.         /* we are running an incompatible version of Ghostscript */
  164.         hwndtext = FindWindow("BCEasyWin","Ghostscript");
  165.         if (hwndtext) {
  166.             SendMessage(hwndtext, WM_CHAR, 'q', 1L);
  167.             SendMessage(hwndtext, WM_CHAR, 'u', 1L);
  168.             SendMessage(hwndtext, WM_CHAR, 'i', 1L);
  169.             SendMessage(hwndtext, WM_CHAR, 't', 1L);
  170.             SendMessage(hwndtext, WM_CHAR, '\r', 1L);
  171.         }
  172.         hwndtext = (HWND)NULL;
  173.         hwndimgchild = (HWND)NULL;
  174.         gswin_hinst = (HINSTANCE)NULL;
  175.         clear_timer();
  176.         pipe_clean();
  177.         info_wait(FALSE);
  178.         gserror(IDS_WRONGGS, NULL, MB_ICONSTOP, SOUND_ERROR);
  179.         return 1;
  180.     }
  181.     saved = FALSE;
  182.     if (set_timer(CLOSE_TIMEOUT))
  183.         EnableWindow(hwndimg, FALSE);
  184.     while (!bPipeDone &&  !bTimeout)
  185.         do_message();    /* wait for pipe data request from gswin */
  186.     clear_timer();
  187.     EnableWindow(hwndimg, TRUE);
  188.     BringWindowToTop(hwndimg);
  189.     SetFocus(hwndimg);    /* kludge: without this desktop gets focus */
  190.     return 0;
  191. }
  192.  
  193. /* close Ghostscript */
  194. int
  195. gswin_close()
  196. {
  197. BOOL force = FALSE;
  198.     if (gswin_hinst == (HINSTANCE)NULL)
  199.         return 0;
  200.  
  201.     if (doc == (struct document*)NULL) {
  202.         /* we don't know how many pages remain so we must force an exit */
  203.         if (!bPipeDone)
  204.         force = TRUE;
  205.     }
  206.     else {
  207.         if (page_ready)
  208.         next_page();
  209.     }
  210.  
  211.     if (!force) {
  212.         /* try to close Ghostscript cleanly */
  213.         pipe_close();
  214.         if (set_timer(CLOSE_TIMEOUT))
  215.         EnableWindow(hwndimg, FALSE);
  216.         while (GetModuleUsage(gswin_hinst) &&  !bTimeout)
  217.         do_message();    /* wait for gswin to close */
  218.         clear_timer();
  219.         EnableWindow(hwndimg, TRUE);
  220.     }
  221.     do_message();
  222.  
  223.     /* if still there try killing it a using a brute force method */
  224.     if (IsWindow(hwndtext)) {
  225.         if (is_win31) {
  226.             SendMessage(hwndtext, WM_CLOSE, 0, 0L);
  227.             if (IsWindow(hwndtext))
  228.             SendMessage(hwndtext, WM_CLOSE, 0, 0L);
  229.         }
  230.         else {
  231.             /* Windows 3.0 hangs if we use SendMessage */
  232.             PostMessage(hwndtext, WM_CLOSE, 0, 0L);
  233.             do_message();
  234.         }
  235.     }
  236.  
  237.     do_message();
  238.     gswin_hinst = (HINSTANCE)NULL;
  239.     hwndimgchild = (HWND)NULL;
  240.     hwndtext = (HWND)NULL;
  241.     bitmap_scrollx = bitmap_scrolly = 0;
  242.     page_ready = FALSE;
  243.     saved = FALSE;
  244.     pipe_clean();
  245.     return 0;
  246. }
  247.  
  248. /* send a NEXT_PAGE message to Ghostscript */
  249. void
  250. next_page()
  251. {
  252. int i;
  253.     if (hwndimgchild && IsWindow(hwndimgchild)) {
  254.         SendMessage(hwndimgchild, WM_GSVIEW, NEXT_PAGE, 0L);
  255.         page_ready = FALSE;
  256.     }
  257.     do_message();    /* wait for Ghostscript to process message */
  258.     for (i=0; i<32; i++) {
  259.        /* Wait a bit for pipe contents after showpage to be read */
  260.        do_message();
  261.        if (bPipeDone)
  262.         break;
  263.     }
  264. }
  265.  
  266. /* handle messages while we are waiting */
  267. void
  268. do_message()
  269. {
  270.     MSG msg;
  271.     while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
  272.     if ((hDlgModeless == 0) || !IsDialogMessage(hDlgModeless, &msg)) {
  273.             TranslateMessage(&msg);
  274.             DispatchMessage(&msg);
  275.         }
  276.     }
  277. }
  278.  
  279.  
  280. /* end of file - get ready for new file */
  281. /* cfile is opened if needed, but not closed */
  282. void
  283. gsview_endfile()
  284. {
  285.     info_wait(TRUE);
  286.     if (gswin_hinst == (HINSTANCE)NULL)
  287.         return;
  288.     if (!quick ||
  289.              ((doc == (struct document *)NULL) && !bPipeDone)) {
  290.         gswin_close();
  291.         return;
  292.     }
  293.  
  294.     if (page_ready)
  295.         next_page();
  296.  
  297.     if (cfile == (FILE *)NULL)
  298.         if (!open_cfile())
  299.             return;
  300.  
  301.     if ((saved) && (doc != (struct document *)NULL) && (doc->pages)) {
  302.         /* send trailer if needed */
  303.             pscopy(dfile, cfile, doc->begintrailer, doc->endtrailer);
  304.     }
  305.     if (saved) {
  306.         /* restore interpreter state */
  307.         fputs("gsview_cleanup\r\n",cfile);
  308.         fputs("gsview_save restore\r\n",cfile);
  309.     }
  310.     else
  311.         fputs("clear cleardictstack\r\n",cfile);
  312.     saved = FALSE;
  313. }
  314.  
  315. /* open a new document */
  316. void
  317. gsview_openfile(char *filename)
  318. {
  319. int i;
  320.     pagenum = 1;
  321.     if (dsc_scan(filename)) {
  322.         /* found DSC comments */
  323.         if (doc->orientation == PORTRAIT)
  324.         gsview_orientation(IDM_PORTRAIT);
  325.         if (doc->orientation == LANDSCAPE)
  326.         gsview_orientation(IDM_LANDSCAPE);
  327.         if (doc->default_page_media) {
  328.         char medianame[20];
  329.         for (i=IDM_LETTER; i<IDM_USERSIZE; i++) {
  330.             GetMenuString(hmenu, i, medianame, sizeof(medianame), MF_BYCOMMAND);
  331.             if (!stricmp(medianame, doc->default_page_media->name)) {
  332.                 gsview_media(i);
  333.                 break;
  334.             }
  335.         }
  336.         if (i == IDM_USERSIZE) {
  337.             gsview_media(IDM_USERSIZE);
  338.             user_width  = doc->default_page_media->width;
  339.             user_height = doc->default_page_media->height;
  340.         }
  341.         }
  342.         is_ctrld = FALSE;
  343.         rewind(dfile);
  344.         if (fgetc(dfile) == '\004')
  345.         is_ctrld = TRUE;
  346.     }
  347. }
  348.  
  349.  
  350. /* get filename then open new file for printing or extract */
  351. void 
  352. gsview_select()
  353. {
  354.     LoadString(phInstance, IDS_TOPICOPEN, szHelpTopic, sizeof(szHelpTopic));
  355.     if (GetOpenFileName(&ofn))
  356.         gsview_selectfile(szOFilename);
  357. }
  358.  
  359. /* open new file for printing or extract */
  360. void
  361. gsview_selectfile(char *filename)
  362. {
  363.     if (gswin_hinst != (HINSTANCE)NULL) {
  364.         gsview_endfile();
  365.         if (cfile != (FILE *)NULL) {
  366.             close_cfile();
  367.             set_timer(timeout);
  368.             pipe_file(cfname);
  369.         }
  370.     }
  371.     gsview_openfile(filename);
  372.     info_wait(FALSE);
  373. }
  374.  
  375. /* get filename then open a new document and display it */
  376. void 
  377. gsview_display()
  378. {
  379.     LoadString(phInstance, IDS_TOPICOPEN, szHelpTopic, sizeof(szHelpTopic));
  380.     if (GetOpenFileName(&ofn))
  381.         gsview_displayfile(szOFilename);
  382. }
  383.  
  384. /* open a new document and display it */
  385. void
  386. gsview_displayfile(char *filename)
  387. {
  388. char *p;
  389.     gsview_endfile();
  390.  
  391.     if (cfile == (FILE *)NULL)
  392.         if (!open_cfile())
  393.             return;
  394.  
  395.     info_wait(TRUE);
  396.  
  397.     gsview_openfile(filename);
  398.     if (epsf_clipped ||
  399.          ((doc != (struct document *)NULL) && doc->epsf && epsf_clip))
  400.         gswin_resize();
  401.  
  402.     fix_orientation(cfile);
  403.     if (doc != (struct document *)NULL) {
  404.         /* found DSC comments */
  405.         dsc_header(cfile);
  406.         dsc_getpages(cfile,pagenum,pagenum);
  407.     }
  408.     else {
  409.         /* non conformant file - send unmodified */
  410.         fputs("(Displaying ",cfile);
  411.         for (p=filename; *p; p++) {
  412.         if (*p != '\\')
  413.             fputc(*p,cfile);
  414.         else
  415.             fputc('/',cfile);
  416.         }
  417.         fputs("\\n) print flush\r\n",cfile);
  418.         fputc('(',cfile);
  419.         for (p=filename; *p; p++) {
  420.         if (*p != '\\')
  421.             fputc(*p,cfile);
  422.         else
  423.             fputc('/',cfile);
  424.         }
  425.         fputs(") run flushpage\r\n",cfile);
  426.     }
  427.     close_cfile();
  428.  
  429.     if (gswin_open())
  430.         return;
  431.     set_timer(timeout);
  432.     saved = TRUE;    /* because gswin_open() killed it */
  433.     pipe_file(cfname);
  434. }
  435.  
  436.  
  437.  
  438. /* add Ghostscript code to change orientation */
  439. void
  440. fix_orientation(FILE *f)
  441. {
  442. int real_orientation;
  443.     /* save interpreter state */
  444.     fputs("clear cleardictstack save /gsview_save exch def\r\n",f);
  445.     saved = TRUE;
  446.     /* define this orientation */
  447.     fputs("/gsview_orientation {\r\n",f);
  448.     if (epsf_clipped) {
  449.         /* provide epsf offset */
  450.         fprintf(f," %d %d translate\r\n",
  451.             -doc->boundingbox[LLX], -doc->boundingbox[LLY]);
  452.     }
  453.     fputs(" gsave clippath pathbbox grestore\r\n",f);
  454.     fputs(" 4 dict begin\r\n",f);
  455.     fputs(" /ury exch def /urx exch def /lly exch def /llx exch def\r\n",f);
  456.     real_orientation = orientation;
  457.     if (swap_landscape) {
  458.         if (orientation == IDM_LANDSCAPE)
  459.         real_orientation = IDM_SEASCAPE;
  460.         else if (orientation == IDM_SEASCAPE)
  461.         real_orientation = IDM_LANDSCAPE;
  462.     }
  463.     switch(real_orientation) {
  464.         case IDM_PORTRAIT:
  465.         break;
  466.         case IDM_LANDSCAPE:
  467.         fputs(" -90 rotate\r\n llx ury add neg llx lly sub translate\r\n",f);
  468.         break;
  469.         case IDM_UPSIDEDOWN:
  470.         fputs(" 180 rotate\r\n llx urx add neg lly ury add neg translate\r\n",f);
  471.         break;
  472.         case IDM_SEASCAPE:
  473.         fputs("  90 rotate\r\n lly llx sub lly urx add neg translate\r\n",f);
  474.         break;
  475.       }
  476.     fputs("  end\r\n} def\r\n",f);
  477.     /* redefine showpage */
  478.     fputs("/showpage\r\n{1 true .outputpage\r\n",f);
  479.     fputs("erasepage initgraphics\r\ngsview_orientation\r\n} bind def\r\n",f);
  480.     /* do the transformation now */
  481.     fputs("gsview_orientation\r\n",f);
  482.     fputs("/gsview_cleanup {clear cleardictstack} def\r\n",cfile);
  483.     if (epsf_warn)
  484.         epsf_warnprolog(f);
  485. }
  486.  
  487. /* open temporary command file */
  488. BOOL
  489. open_cfile()
  490. {
  491.     if (cfile != (FILE *)NULL) {
  492.         close_cfile();
  493.         gserror(IDS_CFILEOPEN, NULL, NULL, SOUND_ERROR);
  494.     }
  495.     /* remove old file */
  496.     if ((cfname[0] != '\0') & !debug)
  497.         unlink(cfname);
  498.     cfname[0] = '\0';
  499.     /* get new scratch file */
  500.     if ( (cfile = gp_open_scratch_file(szScratch, cfname, "wb")) == (FILE *)NULL) {
  501.         info_wait(FALSE);
  502.         gserror(IDS_CFILEERR, NULL, MB_ICONSTOP, SOUND_ERROR);
  503.         return FALSE;
  504.     }
  505.     return TRUE;
  506. }
  507.  
  508. void
  509. close_cfile()
  510. {
  511.     if (cfile)
  512.         fclose(cfile);
  513.     cfile = (FILE *)NULL;
  514. }
  515.  
  516. /* Create and open a scratch file with a given name prefix. */
  517. /* Write the actual file name at fname. */
  518. FILE *
  519. gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
  520. {    char *temp;
  521.     if ( (temp = getenv("TEMP")) == NULL )
  522.         *fname = 0;
  523.     else
  524.     {    strcpy(fname, temp);
  525.         /* Prevent X's in path from being converted by mktemp. */
  526.         for ( temp = fname; *temp; temp++ )
  527.             *temp = tolower(*temp);
  528.         if ( strlen(fname) && (fname[strlen(fname)-1] != '\\') )
  529.             strcat(fname, "\\");
  530.     }
  531.     strcat(fname, prefix);
  532.     strcat(fname, "XXXXXX");
  533.     mktemp(fname);
  534.     return fopen(fname, mode);
  535. }
  536.  
  537. /* scan file for PostScript Document Structuring Conventions */
  538. /* return TRUE if valid DSC comments found */
  539. BOOL
  540. dsc_scan(char *filename)
  541. {
  542. unsigned char eps[4];
  543.     strcpy(dfname, filename);
  544.     if (dfile != (FILE *)NULL)
  545.         fclose(dfile);
  546.     if ( (dfile = fopen(dfname, "rb")) == (FILE *)NULL ) {
  547.         dfname[0] = '\0';
  548.         return FALSE;
  549.     }
  550.     if (page_list.select)
  551.         free(page_list.select);
  552.     page_list.select = NULL;
  553.     if (doc)
  554.         psfree(doc);
  555.     fread(eps, 1, 4, dfile);
  556.     if ((eps[0]==0xc5) && (eps[1]==0xd0) && (eps[2]==0xd3) && (eps[3]==0xc6))
  557.         extract_eps();
  558.     else
  559.         preview = 0;
  560.     doc = psscan(dfile);
  561.     if (doc == (struct document *)NULL) {
  562.         fclose(dfile);
  563.         dfile = (FILE *)NULL;
  564.         return FALSE;
  565.     }
  566.     if (!preview && doc->beginpreview)
  567.         preview = IDS_EPSI;
  568.     page_list.select = (BOOL *)malloc( doc->numpages * sizeof(BOOL) );
  569.     return TRUE;
  570. }
  571.  
  572.  
  573.  
  574. /* Copy specified pages from dfile to file f */
  575. void
  576. dsc_getpages(FILE *f, int first, int last)
  577. {
  578. int i, page;
  579.     for (i=first-1; i<last; i++) {
  580.         page = map_page(i);
  581.         if (doc->pages) {
  582.             fprintf(f,"(Page: %s %d\\n) print flush\r\n", doc->pages[page].label ? doc->pages[page].label : " ", page+1);
  583.         pscopy(dfile, f, doc->pages[page].begin, doc->pages[page].end);
  584.         }
  585.         else {
  586.             fprintf(f,"(Page: %d\\n) print flush\r\n",page); 
  587.         pscopy(dfile, f, doc->endsetup, doc->endtrailer);
  588.         }
  589.     }
  590. }
  591.  
  592.  
  593. /* Copy dsc header to file f */
  594. void
  595. dsc_header(FILE *f)
  596. {
  597. char *p;
  598.     fputs("(Displaying ",f);
  599.     for (p=dfname; *p; p++) {
  600.         if (*p != '\\')
  601.         fputc(*p,f);
  602.         else
  603.         fputc('/',f);
  604.     }
  605.     fputs("\\n) print flush\r\n",f);
  606.     pscopy(dfile, f, doc->beginheader, doc->endheader);
  607.     pscopy(dfile, f, doc->begindefaults, doc->enddefaults);
  608.     pscopy(dfile, f, doc->beginprolog, doc->endprolog);
  609.     pscopy(dfile, f, doc->beginsetup, doc->endsetup);
  610. }
  611.  
  612.  
  613. /* Send commands to gswin to display page */
  614. void
  615. dsc_dopage(void)
  616. {
  617.     info_wait(TRUE);
  618.     if (!open_cfile())
  619.         return;
  620.     if (!saved) {
  621.            fix_orientation(cfile);
  622.            dsc_header(cfile);
  623.     }
  624.     dsc_getpages(cfile,pagenum,pagenum);
  625.     close_cfile();
  626.     set_timer(timeout);
  627.     pipe_file(cfname);
  628. }
  629.  
  630. /* reverse zero based page number if needed */
  631. int
  632. map_page(int page)
  633. {
  634.         if (doc->pageorder == DESCEND) 
  635.         return (doc->numpages - 1) - page;
  636.     return page;
  637. }
  638.  
  639. /* imitation pipe */
  640.  
  641. /* Data is passed in a global shareable memory block.
  642.  * The global handle is passed in the LOWORD of lParam
  643.  * and the HIWORD contains the byte count.
  644.  * The maximum number of bytes passed is PIPE_DATASIZE.
  645.  * EOF is signified by count = 0 (hglobal must still be valid)
  646.  */
  647.  
  648. /* pipe file to gswin */
  649. /* return TRUE if OK, FALSE if pipe overflow or file error */
  650. BOOL
  651. pipe_file(char *fname)
  652. {
  653.     if ((hfPipe!=(HFILE)NULL) || (!bPipeDone)) {
  654.         gserror(IDS_PIPEERR, NULL, NULL, SOUND_ERROR);
  655.         pipe_clean();
  656.         return FALSE;
  657.     }
  658.     hfPipe = _lopen(fname, READ);
  659.     if (hfPipe == HFILE_ERROR) {
  660.         gserror(IDS_PIPEERR, NULL, NULL, SOUND_ERROR);
  661.         return FALSE;
  662.     }
  663.     bPipeDone = FALSE;
  664.     info_wait(TRUE);
  665.     pipe_blk(hfPipe);
  666.     return TRUE;
  667. }
  668.  
  669. /* copy up to PIPE_DATASIZE bytes from file to global block */
  670. /* send block to gswin */
  671. /* return number of bytes sent or -1 for error */
  672. int
  673. pipe_blk(HFILE hf)
  674. {
  675. HGLOBAL hglobal;
  676. LPBYTE lpb;
  677. UINT count;
  678.     hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, PIPE_DATASIZE);
  679.     if (hglobal == (HGLOBAL)NULL) {
  680.         gserror(IDS_PIPEERR, NULL, NULL, SOUND_ERROR);
  681.         return -1;
  682.     }
  683.     lpb = GlobalLock(hglobal);
  684.     count = _lread(hf, lpb, PIPE_DATASIZE);
  685.     GlobalUnlock(hglobal);
  686.     if ((HFILE)count == HFILE_ERROR) {
  687.         GlobalFree(hglobal);
  688.         gserror(IDS_PIPEERR, NULL, NULL, SOUND_ERROR);
  689.         return -1;
  690.     }
  691.     /* we may be processing SendMessage so use PostMessage to avoid lockups */
  692.     if (count)
  693.         PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, MAKELPARAM(hglobal,count));
  694.     else
  695.         GlobalFree(hglobal);
  696.     return count;
  697. }
  698.  
  699. /* send an EOF (zero length block) */
  700. void
  701. pipe_close()
  702. {
  703. HGLOBAL hglobal;
  704.     pipe_clean();
  705.     hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, 1);
  706.     if (hglobal == (HGLOBAL)NULL) {
  707.         gserror(IDS_PIPEERR, NULL, NULL, SOUND_ERROR);
  708.         return;
  709.     }
  710.     PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, MAKELPARAM(hglobal,0));
  711.     
  712. }
  713.  
  714. /* clean up pipe overflow or close empty pipe input file */
  715. void
  716. pipe_clean()
  717. {
  718.     if (hfPipe) {
  719.         _lclose(hfPipe);
  720.         hfPipe = NULL;
  721.         }
  722.     bPipeDone = TRUE;
  723.     clear_timer();
  724.     info_wait(FALSE);
  725. }
  726.